/*
 * File Name: PropertiesUtil.java
 * Created on: 11 de noviembre de 2007, 11:34 AM
 */

package co.edu.uniandes.intercon.server.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;

/**
 * Utility class used to provide property handling mechanism
 * 
 * @author Fabian Gutierrez [fagossa@gmail.com]
 */
public class PropertiesHelper {
    
    /**
     * Property used to get the window initial title
     */
    public final static String TITLE_PROPERTY = "window.title";
    
    /**
     * Property used to get the window initial width
     */
    public final static String WIDTH_PROPERTY = "window.width";
    
    /**
     * Property used to get the window initial height
     */
    public final static String HEIGHT_PROPERTY  = "window.height";
    
    public final static String STARTUP_MODE = "config.startup.mode";
    
    public final static String LOCAL_MODE = "alone";
    
    public final static String REMOTE_MODE = "server";
    
    public final static String SHOW_STATUSBAR = "config.show.statusbar";
    
    public final static String ADVANCED_SEARCH_MODE = "config.advancedsearch";
    
    public final static String SERVER_HOST = "config.server.host";
    
    public final static String SERVER_PORT = "config.server.port";
    
    private final static String CONFIG_FILE = "suncertify.properties";
    
    private static Properties cache = new Properties();
    
    // loads the config file
    static {
        InputStream is = null;
        try {
            is = new FileInputStream(CONFIG_FILE);
            cache.load(is);
        } catch (FileNotFoundException ex) {
            createDefaultConfigFile();
        } catch (IOException ex) {
            P2PLogger.log("General error accesing propertis file. "+ ex.getMessage());
            throw new IllegalStateException("Configuration file could not be created");
        } finally {
            ConnectionHelper.close(is);
        }
    }
    
    /* Avoids instantiation */
    private PropertiesHelper() {        
    }
    
    /**
     * Persist the current properties object
     * @throws  IOException when the file could not be written
     */
    public static void persistProperties() throws IOException {
        OutputStream out = null;
        try {
            out = new FileOutputStream(CONFIG_FILE);
            cache.store(out, "");
        } finally {
            ConnectionHelper.close(out);
        }
    }
    
    /**
     * Sets the property with the name and value specified. If there is already 
     * an existing property with this key, the value is just overwrited
     * 
     * @param key   Name of the property
     * @param value Value of the property
     * @throws AssertionError When the key specified is <code>null</code>
     */
    public static void defineProperty(String key, String value) {
        assert key != null;
        cache.put(key, value);
    }
    
    /**
     * Obtains a property defined in the file {@link #CONFIG_FILE}
     * 
     * @param key   Key of the property to find
     * @return      Value of the property with the key specified or 
     *              <code>null</code> if does not exists
     */
    public static String stringProperty(String key) {        
        return (String)cache.get(key);
    }

    /**
     * Obtains a string property ans transforms it into an int
     * 
     * @param key   Key of the property to find transformed into an 
     *              <code>int</code>
     * @return      Value of the property with the key specified or throws a 
     *              <code>NumberFormatException</code> if the key specified 
     *              could not be found
     * @see #stringProperty(String)
     */
    public static int intProperty(String key) {
        return Integer.parseInt(stringProperty(key));
    }
    
    /**
     * Retrieves an <code>int</code> property based on the <code>string</code> 
     * value returned
     * 
     * @param   key             Key of the property to retrieve
     * @param   defaultValue    Value used when no property could be found with 
     *                          the key specified
     * @return  <code>int</code> value of the property
     */
    public static int intProperty(String key, int defaultValue) {
        int rvalue = 0;
        try {
            rvalue = intProperty(String.valueOf(cache.get(key)));
        } catch(Exception ex) {
            rvalue = defaultValue;
        }
        return rvalue;
    }
    
    /**
     *  Retrieves a <code>String</code> property from the configuration file
     * 
     * @param   key             Key of the property to retrieve
     * @param   defaultValue    Default value used if the property could not be
     *                          found
     * @return  <code>String</code> value of the property
     */
    public static String stringProperty(String key, String defaultValue) {
        String base = stringProperty(key);
        if (base==null) {
            base = defaultValue;
        }
        return base;
    }
    
    /* 
     * Creates an empty configuration file where there is no one specified
     */
    private static boolean createDefaultConfigFile() {
        File file = new File(CONFIG_FILE);
        boolean done = false;
        try {
            if(file.canWrite()) {
                done = file.createNewFile();
            }
        } catch (IOException ioex) {
            throw new IllegalStateException("Configuration file not found and is impossible to recreate it!");
        }
        return done;
    }
    
}
